﻿#include <iostream>
#include <string>
using namespace std;

//class Person
//{
//public:
//	void Print() {
//		cout << "name:" << _name << endl;
//		cout << "age:" << _age << endl;
//	}
////private:
//protected:
////public:
//	string _name = "hhhhh";
//	int _age = 666;
//};
//
//class Student : public Person
//{
//public:
//	void pp(){
//		cout << "age:" << _age << endl;
//	}
//private:
//	int _stuid;
//};
//
//int main()
//{
//	Student a;
//	a.Print();
//
//	cout << "age:" << a._age << endl;
//	a.pp();
//}

//二、基类和派生类对象赋值转换
//class Person
//{
//protected:
//	string _name; // 姓名
//	string _sex;  // 性别
//	int _age; // 年龄
//};
//class Student : public Person
//{
//public:
//	int _No; // 学号
//};
//void Test()
//{
//	Student sobj;
//	// 1.子类对象可以赋值给父类对象/指针/引用
//	Person pobj = sobj;
//	Person* pp = &sobj;
//	Person& rp = sobj;
//
//	//2.基类对象不能赋值给派生类对象
//	sobj = pobj;
//
//	// 3.基类的指针可以通过强制类型转换赋值给派生类的指针
//	pp = &sobj
//		Student * ps1 = (Student*)pp; // 这种情况转换时可以的。
//	ps1->_No = 10;
//
//	pp = &pobj;
//	Student* ps2 = (Student*)pp; // 这种情况转换时虽然可以，但是会存在越界访问的问题
//	
//		ps2->_No = 10;
//}

//三、继承中的作用域
//class Person
//{
//protected:
//	string _name = "张三"; // 姓名
//	int _num = 11; 		// 身份证号
//};
//
//class Student : public Person
//{
//public:
//	void Print()
//	{
//		cout << Person::_num << endl;
//		cout << _num << endl;
//	}
//protected:
//	// 子类和父类中有同名成员，子类成员将屏蔽父类对同名成员的直接访问，这种情况叫隐藏，也叫重定义。
//	int _num = 666; // 学号
//};

// B中的fun和A中的fun不是构成重载，因为不是在同一作用域
// B中的fun和A中的fun构成隐藏，成员函数满足函数名相同就构成隐藏
//class A
//{
//public:
//	void fun()
//	{
//		cout << "func()" << endl;
//	}
//};
//class B : public A
//{
//public:
//	void fun(int i)
//	{
//		cout << "func(int i)->" << i << endl;
//	}
//};
//
//// A：两个fun构成函数重载
//// B：两个fun构成隐藏
//// C：编译报错
//// D：以上说法都不对
//
//void Test()
//{
//	B b;
//	b.fun(10); //访问B中的fun
//	b.A::fun();//访问A中的fun
//};
//
//int main()
//{
//	//Student s;
//	//s.Print();
//
//	return 0;
//}

//四、派生类的默认成员函数
//class Person
//{
//public:
//	Person(const char* name = "peter")
//		: _name(name)
//	{
//		cout << "Person()" << endl;
//	}
//
//	Person(const Person& p)
//		: _name(p._name)
//	{
//		cout << "Person(const Person& p)" << endl;
//	}
//
//	Person& operator=(const Person& p)
//	{
//		cout << "Person operator=(const Person& p)" << endl;
//		if (this != &p)
//			_name = p._name;
//
//		return *this;
//	}
//
//	~Person()
//	{
//		cout << "~Person()" << endl;
//	}
//protected:
//	string _name; // 姓名
//};
//
//class Student : public Person
//{
//public:
//	Student(const char* name, int num)
//		:Person(name)
//		, _num(num)
//	{
//		cout << "Student()" << endl;
//	}
//
//	Student(const Student& s)
//		:Person(s)
//		, _num(s._num)
//	{
//		cout << "Student(const Student& s)" << endl;
//
//	}
//
//	// 20:35继续
//	Student& operator=(const Student& s)
//	{
//		if (this != &s)
//		{
//			Person::operator=(s);
//			_num = s._num;
//		}
//		cout << "Student& operator=(const Student& s)" << endl;
//
//
//		return *this;
//	}
//
//	// 析构函数会被处理成destructor
//	~Student()
//	{
//		//Person::~Person();//不需要显示调用，会多调用一次
//
//		cout << "~Student()" << endl;
//	}
//	// 子类析构函数完成时，会自定调用父类析构函数，保证先析构子再析构父
//protected:
//	int _num; //学号
//};
//
//// 21:00继续
//int main()
//{
//	Student s1("张三", 18);
//	Student s2(s1);
//
//	Person p = s1;
//
//	s1 = s2;
//
//
//	return 0;
//}

//五、继承与友元
//class Student;
//class Person
//{
//public:
//	friend void Display(const Person& p, const Student& s);
//protected:
//	string _name; // 姓名
//};
//class Student : public Person
//{
//	//添加下面这句就可以解决
//	//friend void Display(const Person& p, const Student& s);
//protected:
//	int _stuNum; // 学号
//};
//
//void Display(const Person& p, const Student& s)
//{
//	cout << p._name << endl;
//	cout << s._stuNum << endl;
//}
//
//int main()
//{
//	Person p;
//	Student s;
//	Display(p, s);
//}


//六、继承与静态成员
//class Person
//{
//public:
//	Person() { ++_count; }
////protected:
//	string _name; // 姓名
//public:
//	static int _count; // 统计人的个数。
//};
//int Person::_count = 0;
//
//class Student : public Person
//{
//protected:
//	int _stuNum; // 学号
//};
//
//class Graduate : public Student
//{
//protected:
//	string _seminarCourse; 
//};
//
//int main()
//{
//	Person p;
//	Student s;
//	//地址不同
//	 cout << &(p._name) << endl;
//	 cout << &(s._name) << endl;
//
//	//地址相同
//	 cout << &(p._count) << endl;
//	 cout << &(s._count) << endl;
//
//	//计算创建的对象的个数
//	Graduate g1;
//	Graduate g2;
//
//	cout << Person::_count << endl;
//	cout << Graduate::_count << endl;
//
//	return 0;
//}
//
////实现一个不能被继承的类
//class A
//{
//public:
//	static A CreateObj()
//	{
//		return A();
//	}
//private:
//	A()
//	{}
//};
//
//class B : public A
//{};
//
//int main()
//{
//	A::CreateObj();
//
//	//B bb;
//
//	return 0;
//}


//class Person
//{
//public:
//	string _name; // 姓名
//};
//class Student : virtual public Person
//{
//protected:
//	int _num; //学号
//};
//class Teacher : virtual public Person
//{
//protected:
//	int _id; // 职工编号
//};
//class Assistant : public Student, public Teacher
//{
//protected:
//	string _majorCourse; // 主修课程
//};
//
//void Test()
//{
//	// 这样会有二义性无法明确知道访问的是哪一个
//	Assistant a;
//	a._name = "peter";
//
//	// 需要显示指定访问哪个父类的成员可以解决二义性问题，但是数据冗余问题无法解决
//	a.Student::_name = "xxx";
//	a.Teacher::_name = "yyy";
//}

class Person
{
public:
	Person() { ++_count; }
	//protected:
	string _name; // 姓名
public:
	static int _count; // 统计人的个数。
};
int Person::_count = 0;

class Student : public Person
{
protected:
	int _stuNum; // 学号
};

class Graduate : public Student
{
protected:
	string _seminarCourse;
};
int main()
{
	Person p;
	Student s;
	//地址不同
	cout << &(p._name) << endl;
	cout << &(s._name) << endl;

	//地址相同
	cout << &(p._count) << endl;
	cout << &(s._count) << endl;

	//计算创建的对象的个数
	Graduate g1;
	Graduate g2;

	cout << Person::_count << endl;
	cout << Graduate::_count << endl;

	return 0;
}